<script>
export default {
  name: "customForm",
  props: {
    gutter: {
      //间距
      type: Number,
      default() {
        return 10;
      },
    },
    col: {
      //一行显示几个元素
      type: Number,
      default() {
        return 3;
      },
    },
    labelWidth: {
      //label宽度
      type: String,
      default() {
        return "150px";
      },
    },
    labelPosition: {
      type: String,
      validator(value) {
        return ["right", "left", "top"].includes(value);
      },
      default() {
        return "right";
      },
    },
    list: {
      type: Array,
      default() {
        return [];
      },
    },
    defaultForm: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  computed: {
    columnLayout: {
      get() {
        return 24 / this.col;
      },
    },
  },
  data() {
    return {
      form: {},
    };
  },
  methods: {
    renderForm() {
      const { gutter, form, labelWidth, labelPosition, list, defaultForm } =
        this;
      return (
        <el-row gutter={gutter}>
          <el-form
            ref="form"
            attrs={{ model: form }}
            labelWidth={labelWidth}
            labelPosition={labelPosition}
          >
            {list.map((column, i) => this.renderColumn(column, i))}
            {
              <el-col
                style={{ display: "flex", justifyContent: "end" }}
                span={(3 - (list.length % 3)) * this.columnLayout}
              >
                <el-button
                  type="primary"
                  onClick={() => {
                    this.$emit("searchFn", this.form);
                  }}
                >
                  查询
                </el-button>
                <el-button
                  onClick={() => {
                    this.form = {};
                  }}
                >
                  重置
                </el-button>
              </el-col>
            }
          </el-form>
        </el-row>
      );
    },
    renderColumn(column, i) {
      const { columnLayout } = this;
      return (
        <el-col span={columnLayout}>
          {this.$scopedSlots[column.prop] ? (
            this.$scopedSlots[column.prop]({ data: this.form, column })
          ) : (
            <el-form-item
              key={i}
              label={column.label + ":"}
              prop={column.prop}
              rules={column.rules}
            >
              {
                <div
                  slot="label"
                  style={{ background: "#f4f4f4", textIndent: "10px" }}
                >
                  {column.label}
                </div>
              }
              {this.renderItem(column)}
            </el-form-item>
          )}
        </el-col>
      );
    },
    renderRadio(radioItem) {
      return <el-radio label={radioItem.key}>{radioItem.value}</el-radio>;
    },
    renderSelectOption(option, index) {
      return (
        <el-option
          key={option.key + "_" + index}
          label={option.label}
          value={option.key}
        ></el-option>
      );
    },
    renderItem(column) {
      const { form } = this;
      const type = column.type || "input";
      switch (type) {
        case "input":
          return (
            <el-input
              clearable
              placeholder={column.placeholder || "请输入"}
              v-model={form[column.prop]}
            ></el-input>
          );
        case "textarea":
          return <el-input v-model={form[column.prop]} type={type}></el-input>;
        case "date":
          return (
            <el-date-picker
              type={type}
              placeholder="选择日期"
              style="width:100%"
              v-model={form[column.prop]}
            />
          );
        case "radio":
          return (
            <el-radio-group v-model={form[column.prop]}>
              {column.radioList.map((radioItem) => this.renderRadio(radioItem))}
            </el-radio-group>
          );
        case "select":
          return (
            <el-select
              style="width:100%"
              v-model={form[column.prop]}
              placeholder="请选择"
            >
              {column.optionList.map((option, index) =>
                this.renderSelectOption(option, index)
              )}
            </el-select>
          );
        default:
          throw new Error(
            `customForm组件中未含有${type}类型表单组件,请检type是否属于input,textarea,date类型`
          );
      }
    },
  },
  render() {
    return this.renderForm();
  },
  watch: {
    defaultForm: {
      handler(v, o) {
        this.form = v;
      },
      immediate: true,
    },
  },
};
</script>
<style lang="less" scoped>
:deep(.el-form-item) {
  margin-bottom: 10px;
}
</style>
